<?php

/**
 * lazada  
 */
class PlatformAPIClient_Lazada extends PlatformAPIClient_Abstract {
    
    /**
     * auth
     * @var type 
     */
    private $_auth = null;
    
    /**
     * client
     * @var type 
     */
    private $_client = null;    
    
    /**
     * 初始化
     * @param type $option
     */
    public function __construct($option = array()) {
        
        parent::__construct($option);
        
        require_once dirname(dirname(__FILE__)) . '/third-lib/lazop/LazopSdk.php';
        $url = $option['api_url'];
        $this->_client = new LazopClient($url, $option['app_key'], $option['app_secret']);

        $cacheKey = 'lazada-auth:'.$option['shop_name'];
        $cache = PlatformAPIClient::getCacheHandler();
        $authInfo = $cache->get($cacheKey);
        // 通过code获取授权
        if (empty($authInfo)) {
            
            // 获取 code
            if (empty($option['code_callback']) || !is_callable($option['code_callback'])) {
                throw new Exception('bad callback for get lazada auth code');
            }
            $code = call_user_func($option['code_callback'], $option);
            if (!$code) {
                throw new Exception('call lazada auth code callback failed.');
            }
            
            $url = 'https://auth.lazada.com/rest';
            $c = new LazopClient($url, $option['app_key'], $option['app_secret']);
            $request = new LazopRequest('/auth/token/create', 'GET');
            $request->addApiParam('code', $code);
    //        $request->addApiParam('uuid', crc32(SHOP_NAME).'#'.time());
            $result = $c->execute($request);
            $data = json_decode($result, true);
            if ($data && !empty($data['access_token']) && !empty($data['expires_in'])) {
                $authInfo = $data;
                $authInfo['refresh_time'] = time() + $authInfo['expires_in'];
                $cache->set($cacheKey, $authInfo, $authInfo['expires_in']);
            } else {
                throw new Exception('create token failed. return: ' . $result);
            }
        }
        if (empty($authInfo)) {
            throw new Exception('get auth failed!');
        }
        
        // 即将到期，续约一次
        if ($authInfo['refresh_time'] - time() <= 43200) {
            $url = 'https://auth.lazada.com/rest';
            $c = new LazopClient($url, $option['app_key'], $option['app_secret']);
            $request = new LazopRequest('/auth/token/refresh', 'GET');
            $request->addApiParam('refresh_token', $authInfo['refresh_token']);
            $result = $c->execute($request);
            $data = json_decode($result, true);
            if ($data && !empty($data['access_token']) && !empty($data['expires_in'])) {
                $authInfo = $data;
                $authInfo['refresh_time'] = time() + $authInfo['expires_in'];
                $cache->set($cacheKey, $authInfo, $authInfo['expires_in']);
            } else {
                throw new Exception('refresh token failed. return: ' . $result);
            }
        }
        $this->_auth = $authInfo['access_token'];

        if (!$this->_auth) {
            throw new Exception('shop not supported!');
        }
    }

    /**
     * 根据条件获取订单列表
     * @param type $conditions
     * @return array
     */
    public function getOrderList($conditions) {
        
        $params = [
            'status' => 'pending',
            'created_after' => date('Y-m-d', time() - 86400 * 3) . 'T00:00:00+07:00',
            'offset' => 0,
            'limit' => 10,
        ];
        $params = array_merge($params, $conditions);

        $request = new LazopRequest('/orders/get', 'GET');
        // Possible values are unpaid, pending, canceled, ready_to_ship, delivered, returned, shipped and failed.
        $request->addApiParam('status', 'pending');
        $request->addApiParam('created_after', $params['created_after']);
        $request->addApiParam('offset', $params['offset']);
        $request->addApiParam('limit', $params['limit']);
        $result = $this->_client->execute($request, $this->_auth);
        $data = json_decode($result, true);
        if (!$data || empty($data['data'])) {
            throw new Exception('get orders failed. result: ' . $result);
        }
        return $data['data']['orders'];
    }

    /**
     * 获取指定订单信息
     */
    public function getOrder($orderId) {

        try {
            $request = new LazopRequest('/order/get', 'GET');
            $request->addApiParam('order_id', $orderId);
            $result = $this->_client->execute($request, $this->_auth);
            $data = json_decode($result, true);
        } catch (Exception $e) {
            throw new Exception('get lazada order failed: '.$e->getMessage());
        }
        if (!$data || empty($data['data'])) {
            throw new Exception('get lazada order failed. result: '.$result);
        }
        $order = $data['data'];

        try {
            $request = new LazopRequest('/order/items/get', 'GET');
            $request->addApiParam('order_id', $orderId);
            $result = $this->_client->execute($request, $this->_auth);
            $data = json_decode($result, true);
        } catch (Exception $e) {
            throw new Exception('get lazada order items failed: '.$e->getMessage());
        }
        if (!$data || empty($data['data'])) {
            throw new Exception('get lazada order items failed. result: '.$result);
        }
        $order['items'] = $data['data'];

        return $order;
    }

    /**
     * 设置指定 sku 在平台的库存量
     * @param type $sku
     * @param type $stock
     */
    public function setStock($sku, $stock) {
        
        if (!isset($sku['sku_id'])) {
            throw new Exception('invalid sku info: '.json_encode($sku));
        }
        if ($stock < 0) {
            throw new Exception('invalid stock: '.$stock);
        }

        $content = '<Request>';
        $content .= '  <Product>';
        $content .= '    <Skus>';
        $content .= '      <Sku>';
        $content .= '        <SellerSku>'.trim($sku['sku_id']).'</SellerSku>';
        $content .= '        <Quantity>'.intval($stock).'</Quantity>';
        $content .= '        <Price/>';
        $content .= '        <SalePrice/>';
        $content .= '        <SaleStartDate/>';
        $content .= '        <SaleEndDate/>';
        $content .= '      </Sku>';
        $content .= '    </Skus>';
        $content .= '  </Product>';
        $content .= '</Request>';
//        $content = str_replace('  ', '', $content);
        try {
            $request = new LazopRequest('/product/price_quantity/update');
            $request->addApiParam('payload', $content);
            $result = $this->_client->execute($request, $this->_auth);
            return $result;
        } catch (Exception $e) {
            throw new Exception('lazada update item stock failed: '.$e->getMessage());
        }
    }
}